package com.gln.bloger.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.gln.bloger.dao.BaseDao;
import com.gln.bloger.exception.BlogerException;
/**
 * 
 * @author nicholas ren
 *
 * @param <T>
 */
public  abstract class BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T> {
	
	/**
	 * class type
	 */
	private Class<T> entityClass;
	/**
	 *getGenericSuperclass()
     * Returns the Type representing the direct superclass of the entity 
     *(class, interface, primitive type or void) represented by this Class.
     *ParameterizedType
     * getActualTypeArguments()
     * Returns an array of Type objects representing the actual type arguments to this type.
	 */
	@SuppressWarnings("unchecked")
	public BaseDaoImpl(){
		entityClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}
	/**
	 * get domain by id
	 */
	@SuppressWarnings("unchecked")
	public T get(String id) throws BlogerException {
		T entity = (T) getHibernateTemplate().get(entityClass, id);
		return entity;
	}
	
	@SuppressWarnings("unchecked")
	public T load(String id) throws BlogerException{
		T entity = (T) getHibernateTemplate().load(entityClass, id);
		return entity;
	}

	/**
	 * get domain by name
	 * @param name
	 * @return
	 * @throws BlogerException
	 */
	@SuppressWarnings("unchecked")
	public T getByName(String name) throws BlogerException {
		//make criteria
		DetachedCriteria criteria = DetachedCriteria.forClass(entityClass);
        criteria.add(Restrictions.eq("name", name));
        List<T> entities = getHibernateTemplate().findByCriteria(criteria);
        if(entities.size() > 0){
        	return entities.get(0);
        }else{
        	return null;
        }
	}

	/**
	 * get by criteria
	 */
	@SuppressWarnings("unchecked")
	public List<T> getListByCriteria(DetachedCriteria detachedCriteria)
			throws BlogerException {
		return getHibernateTemplate().findByCriteria(detachedCriteria);
	}

	/**
	 * save or update domain
	 */
	public void saveOrUpdate(T t) throws BlogerException {
		getHibernateTemplate().saveOrUpdate(t);
	}
	
	public void remove (T t) throws BlogerException{
		getHibernateTemplate().delete(t);
	}
	
	@SuppressWarnings("unchecked")
	public List<T> list() throws BlogerException{
		return (List<T>)getHibernateTemplate().loadAll(entityClass);
	}
}
